require('dotenv').config();
const express = require('express');
const cors = require('cors');
const Web3 = require('web3');
const fs = require('fs');
const path = require('path');

const app = express();
const PORT = process.env.PORT || 3001;

// 中间件
app.use(cors());
app.use(express.json());

// Web3 设置
const web3 = new Web3(process.env.RPC_URL);
const contractABI = JSON.parse(fs.readFileSync(path.join(__dirname, 'abi.json'), 'utf8'));
const contract = new web3.eth.Contract(contractABI, process.env.CONTRACT_ADDRESS);

// API路由

// 获取项目统计信息
app.get('/api/stats', async (req, res) => {
    try {
        const projectCount = await contract.methods.getTotalProjects().call();
        const platformWallet = await contract.methods.platformWallet().call();
        const platformFeePercentage = await contract.methods.platformFeeRate().call();
        
        let activeProjects = 0;
        let successfulProjects = 0;
        let totalRaised = web3.utils.toBN(0);
        
        for (let i = 0; i < projectCount; i++) {
            const project = await contract.methods.projects(i).call();
            if (project.status == 0) activeProjects++;
            if (project.status == 1) successfulProjects++;
            totalRaised = totalRaised.add(web3.utils.toBN(project.currentAmount));
        }
        
        res.json({
            projectCount: projectCount.toString(),
            activeProjects,
            successfulProjects,
            totalRaised: web3.utils.fromWei(totalRaised, 'ether'),
            platformFeePercentage: platformFeePercentage.toString(),
            platformWallet
        });
    } catch (error) {
        console.error('Error fetching stats:', error);
        res.status(500).json({ error: 'Failed to fetch statistics' });
    }
});

// 获取所有项目
app.get('/api/projects', async (req, res) => {
    try {
        const projectCount = await contract.methods.getTotalProjects().call();
        const projects = [];
        
        for (let i = 0; i < projectCount; i++) {
            const project = await contract.methods.projects(i).call();
            projects.push({
                id: i,
                ...project,
                currentAmount: web3.utils.fromWei(project.currentAmount, 'ether'),
                goalAmount: web3.utils.fromWei(project.goalAmount, 'ether')
            });
        }
        
        res.json(projects);
    } catch (error) {
        console.error('Error fetching projects:', error);
        res.status(500).json({ error: 'Failed to fetch projects' });
    }
});

// 获取单个项目详情
app.get('/api/projects/:id', async (req, res) => {
    try {
        const projectId = req.params.id;
        const project = await contract.methods.projects(projectId).call();
        const contributors = await contract.methods.getProjectContributors(projectId).call();
        
        const contributorDetails = await Promise.all(
            contributors.map(async (contributor) => {
                const amount = await contract.methods.getUserContribution(projectId, contributor).call();
                return {
                    address: contributor,
                    amount: web3.utils.fromWei(amount, 'ether')
                };
            })
        );
        
        res.json({
            id: projectId,
            ...project,
            currentAmount: web3.utils.fromWei(project.currentAmount, 'ether'),
            goalAmount: web3.utils.fromWei(project.goalAmount, 'ether'),
            contributors: contributorDetails
        });
    } catch (error) {
        console.error('Error fetching project details:', error);
        res.status(500).json({ error: 'Failed to fetch project details' });
    }
});

// 获取用户的项目
app.get('/api/users/:address/projects', async (req, res) => {
    try {
        const userAddress = req.params.address;
        
        // 获取用户创建的项目
        const createdProjects = await contract.methods.getUserCreatedProjects(userAddress).call();
        
        // 获取用户投资的项目
        const contributedProjects = await contract.methods.getUserParticipatedProjects(userAddress).call();
        
        // 获取详细信息
        const createdDetails = await Promise.all(
            createdProjects.map(async (projectId) => {
                const project = await contract.methods.projects(projectId).call();
                return {
                    id: projectId.toString(),
                    ...project,
                    currentAmount: web3.utils.fromWei(project.currentAmount, 'ether'),
                    goalAmount: web3.utils.fromWei(project.goalAmount, 'ether')
                };
            })
        );
        
        const contributedDetails = await Promise.all(
            contributedProjects.map(async (projectId) => {
                const project = await contract.methods.projects(projectId).call();
                const contribution = await contract.methods.getUserContribution(projectId, userAddress).call();
                return {
                    id: projectId.toString(),
                    ...project,
                    currentAmount: web3.utils.fromWei(project.currentAmount, 'ether'),
                    goalAmount: web3.utils.fromWei(project.goalAmount, 'ether'),
                    userContribution: web3.utils.fromWei(contribution, 'ether')
                };
            })
        );
        
        res.json({
            created: createdDetails,
            contributed: contributedDetails
        });
    } catch (error) {
        console.error('Error fetching user projects:', error);
        res.status(500).json({ error: 'Failed to fetch user projects' });
    }
});

// 检查项目状态（手动触发检查超时项目）
app.post('/api/projects/check-status', async (req, res) => {
    try {
        const projectCount = await contract.methods.getTotalProjects().call();
        const checkedProjects = [];
        
        for (let i = 0; i < projectCount; i++) {
            const project = await contract.methods.projects(i).call();
            
            // 只检查活跃项目
            if (project.status == 0) {
                const endTime = parseInt(project.startTime) + parseInt(project.duration);
                const now = Math.floor(Date.now() / 1000);
                
                if (now > endTime) {
                    checkedProjects.push({
                        id: i,
                        title: project.title,
                        expired: true,
                        reached: project.currentAmount >= project.goalAmount
                    });
                }
            }
        }
        
        res.json({
            message: 'Status check completed',
            checkedProjects
        });
    } catch (error) {
        console.error('Error checking project status:', error);
        res.status(500).json({ error: 'Failed to check project status' });
    }
});

// 获取成功率
app.get('/api/success-rate', async (req, res) => {
    try {
        const rate = await contract.methods.getProjectSuccessRate().call();
        res.json({ 
            successRate: rate.toString(),
            successRatePercentage: (rate / 100).toFixed(2)
        });
    } catch (error) {
        console.error('Error fetching success rate:', error);
        res.status(500).json({ error: 'Failed to fetch success rate' });
    }
});

// 健康检查
app.get('/api/health', async (req, res) => {
    try {
        const blockNumber = await web3.eth.getBlockNumber();
        const chainId = await web3.eth.getChainId();
        
        res.json({
            status: 'ok',
            blockNumber: blockNumber.toString(),
            chainId: chainId.toString(),
            contractAddress: process.env.CONTRACT_ADDRESS,
            rpcUrl: process.env.RPC_URL
        });
    } catch (error) {
        console.error('Health check failed:', error);
        res.status(500).json({ 
            status: 'error',
            error: error.message 
        });
    }
});

// 启动服务器
app.listen(PORT, () => {
    console.log(`Server running on port ${PORT}`);
    console.log(`Connected to RPC: ${process.env.RPC_URL}`);
    console.log(`Contract address: ${process.env.CONTRACT_ADDRESS}`);
});